package com.ftwj.demo.config.quartz;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.ftwj.demo.utils.date.DateHelper;
import com.ftwj.demo.utils.exception.ScheduleException;
import com.ftwj.demo.utils.json.JsonUtil;
import com.ftwj.demo.utils.logs.LoggerUtil;

import net.sf.ehcache.search.SearchException;

/**
 * <p>Title: QuartzManager</p>  
 * <p>Description: 调度任务</p>
 * <p>Copyright: Copyright (c) 2020 </p>  
 * <p>Company: 兰州飞天网景信息产业有限公司</p>    
 * @author HeYang
 * @date 2020年4月16日 下午3:34:59
 * @version V1.0
 */
@Configuration
public class QuartzManager {
	
    /**
     * 
     * <p>Title: buildJobInformation</p>  
     * <p>Description: </p>  
     * @param scheduler 调度器
     * @param jobName   job名称
     * @param groupName 分组名称
     * @param cron      cron表达式
     * @param className  job类的全局限定名
     * @param params    job中需要的 参数
     * @return 
     * @author WangSLi
     * @date 2020年4月17日  
     * @version 1.0
     * @throws ClassNotFoundException 
     */
	@SuppressWarnings("unchecked")
	public JobInformation buildJobInformation(String jobName,String groupName,String desc,String cron,String className,String params) {
		JobInformation information = new JobInformation();
		//1.创建jobDetail
		try {
			Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(className);
			JobDataMap dataMap = new JobDataMap(JsonUtil.toJsonObject(params));
			JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName,groupName).withDescription(desc).setJobData(dataMap).build();
			information.setJob(jobDetail);
		} catch (ClassNotFoundException e) {
			LoggerUtil.error("任务【{}】不存在",className);
		}
		//2.创建基于cron表达式的定时触发器
		try {
			CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
			CronTrigger cronTrigger=TriggerBuilder.newTrigger().withIdentity(jobName,groupName).withSchedule(cronScheduleBuilder).build();
			information.setTrigger(cronTrigger);
		} catch (Exception e) {
			LoggerUtil.error("cron触发器创建【{}】失败",cron);
			throw new ScheduleException("cron触发器创建【"+cron+"】失败");
		}
		return information;
	}
    
	
	/**
     * 	任务调度
     */
    @Autowired
    private Scheduler scheduler;
    
    /**
     * <p>Title: startJobTask</p>  
     * <p>Description: 创建调度任务</p>  
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
	public boolean startJobTask(JobInformation information){
		try {
	        //4.将工作与定时器加入到调度器
	        Date date = scheduler.scheduleJob(information.getJob(),information.getTrigger());
	        scheduler.start();
	        LoggerUtil.debug("调度器启动成功,时间：{}，状态：{}",DateHelper.formatDate(date),"已开启");
	        return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("开启调度器异常");
		}
		return false;
    }
	/**
     * <p>Title: startJobTask</p>  
     * <p>Description: 创建调度任务,但处于暂停状态</p>  
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
	public boolean startPauseJobTask(JobInformation information){
		try {
	        //4.将工作与定时器加入到调度器
	        Date date = scheduler.scheduleJob(information.getJob(),information.getTrigger());
	        scheduler.pauseJob(information.getJob().getKey());
	        LoggerUtil.debug("调度器启动成功,时间：{}，状态：{}",DateHelper.formatDate(date),"已开启");
	        return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("开启调度器异常");
		}
		return false;
    }
    
    /**
     * <p>Title: getjobInfo</p>  
     * <p>Description: 获取运行状态</p>  
     * @param name
     * @param group
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public String getJobInfo(String jobName,String groupName) {
    	try {
    	TriggerKey triggerKey=new TriggerKey(jobName,groupName);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			if(cronTrigger!=null) {
				return String.format("corn表达式:%s,运行状态:%s"
						,cronTrigger.getCronExpression()
						,scheduler.getTriggerState(cronTrigger.getKey()).name());
			}
			return String.format("corn表达式:%s,运行状态:%s","0 0 0 0 0 ?","不存在");
		} catch (SchedulerException e) {
			LoggerUtil.error("调度器状态获取失败");
		}
		return "调度器状态获取失败";
    }
    
    /**
     * <p>Title: modifyJob</p>  
     * <p>Description: 通过jobName和groupName修改定时器中的cron表达式</p>  
     * @param name
     * @param group
     * @param cron
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean modifyJob(String jobName,String groupName,String cron){
        TriggerKey triggerKey=new TriggerKey(jobName, groupName);
		try {
			CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			if(cronTrigger==null) {
				throw new SearchException("Cron触发器不存在！");
			}
			String old=cronTrigger.getCronExpression();
	        if (!old.equalsIgnoreCase(cron)){
	            CronScheduleBuilder cronScheduleBuilder=CronScheduleBuilder.cronSchedule(cron);
	            CronTrigger trigger=TriggerBuilder.newTrigger()
	            			.withIdentity(jobName,groupName)
	            			.withSchedule(cronScheduleBuilder).build();
	            Date date=scheduler.rescheduleJob(triggerKey,trigger);
	            LoggerUtil.debug("调度器修改成功,时间：{}",DateHelper.formatDate(date));
	        }
	        return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("调度器cron修改失败");
			return false;
		}
        
    }
    
    /**
     * <p>Title: pauseAllJob</p>  
     * <p>Description: 暂停当前所有调度器</p>  
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean pauseAllJob(){
        try {
			scheduler.pauseAll();
			return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("暂停当前所有调度器失败");
		}
        return false;
    }
    
    /**
     * <p>Title: pauseJob</p>  
     * <p>Description: 暂停指定调度任务</p>  
     * @param name
     * @param group
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean pauseJob(String jobName,String groupName){
        JobKey jobKey=new JobKey(jobName,groupName);
		try {
			scheduler.pauseJob(jobKey);
	        return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("暂停当前调度器失败");
		}
		return false;
    }
    
    /**
     * <p>Title: restartAllJob</p>  
     * <p>Description: 重启所有暂停的调度任务</p>  
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean restartAllJob(){
        try {
			scheduler.resumeAll();
			return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("重启所有暂停的调度任务失败");
		}
        return false;
    }
    
    /**
     * <p>Title: restartJob</p>  
     * <p>Description: 重启某个暂停的任务</p>  
     * @param jobName
     * @param groupName
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean restartJob(String jobName,String groupName){
        JobKey jobKey=new JobKey(jobName,groupName);
		try {
			scheduler.resumeJob(jobKey);
	        return true;
		} catch (SchedulerException e) {
			LoggerUtil.error("重启暂停的调度任务失败：{}",jobName);
		}
		return false;
    }
    
    /**
     * <p>Title: deleteJob</p>  
     * <p>Description: 删除调度任务</p>  
     * @param jobName
     * @param groupName
     * @throws SchedulerException 
     * @author HeYang
     * @date 2020年4月16日  
     * @version 1.0
     */
    public boolean remoJob(String jobName,String groupName){
        JobKey jobKey=new JobKey(jobName, groupName);
		try {
			return scheduler.deleteJob(jobKey);
		} catch (SchedulerException e) {
			LoggerUtil.error("删除调度任务失败");
		}
		return false;
    }

}
